#include "daf_user_entry.h"
#include "daf_user_param.h"
#include "daf_user_control.h"
#include "wf_manager.h"

#include "daf/daf_param.h"
#include "daf/daf_control.h"

#include "gazella/logger.h"
#include "../agent/wf_manager.h"

namespace Gazella
{
    namespace Daf
    {

        // tsl.thing
        static DafUserEntry entry("wf");

        DafUserEntry::DafUserEntry(const std::string &name) : IDafEntry(name)
        {
        }

        DafUserEntry::~DafUserEntry()
        {
        }

        // auto generate, don't modify
        bool DafUserEntry::daf_entry(int argc, char *argv[])
        {
            // connect control callback functions

            // connect lockCtl(lockCtl) control callback
            DafControl::get_instance()->connect(
                "lockCtl",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect takeoff(takeoff) control callback
            DafControl::get_instance()->connect(
                "takeoff",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect return(return) control callback
            DafControl::get_instance()->connect(
                "return",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect land(land) control callback
            DafControl::get_instance()->connect(
                "land",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect hover(hover) control callback
            DafControl::get_instance()->connect(
                "hover",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect flyTo(moveToLocation) control callback
            DafControl::get_instance()->connect(
                "flyTo",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect speedM(moveBySpeed) control callback
            DafControl::get_instance()->connect(
                "speedM",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect ctlJoy(ctlJoy) control callback
            DafControl::get_instance()->connect(
                "ctlJoy",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect navFly(upNavDataAndFly) control callback
            DafControl::get_instance()->connect(
                "navFly",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect resumeNav(resumeNav) control callback
            DafControl::get_instance()->connect(
                "resumeNav",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect stopNav(stopNav) control callback
            DafControl::get_instance()->connect(
                "stopNav",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect takePhoto(takePhoto) control callback
            DafControl::get_instance()->connect(
                "takePhoto",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect startVideo(startVideo) control callback
            DafControl::get_instance()->connect(
                "startVideo",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect stopVideo(stopVideo) control callback
            DafControl::get_instance()->connect(
                "stopVideo",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect zoomIn(zoomIn) control callback
            DafControl::get_instance()->connect(
                "zoomIn",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect zoomOut(zoomOut) control callback
            DafControl::get_instance()->connect(
                "zoomOut",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect zoomScale(zoomScale) control callback
            DafControl::get_instance()->connect(
                "zoomScale",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect gimbalFollow(gimbalFollow) control callback
            DafControl::get_instance()->connect(
                "gimbalFollow",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect gimbalReset(gimbalReset) control callback
            DafControl::get_instance()->connect(
                "gimbalReset",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect gimbalFree(gimbalFreeCtl) control callback
            DafControl::get_instance()->connect(
                "gimbalFree",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect gimbalLeft(gimbalLeftCtl) control callback
            DafControl::get_instance()->connect(
                "gimbalLeft",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect gimbalRight(gimbalRightCtl) control callback
            DafControl::get_instance()->connect(
                "gimbalRight",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect gimbalUp(gimbalUpCtl) control callback
            DafControl::get_instance()->connect(
                "gimbalUp",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect gimbalDown(gimbalDownCtl) control callback
            DafControl::get_instance()->connect(
                "gimbalDown",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect weaponSwitch(weaponInsuranceSwitch) control callback
            DafControl::get_instance()->connect(
                "weaponSwitch",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect sShot(singleShot) control callback
            DafControl::get_instance()->connect(
                "sShot",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect rShot(runningShot) control callback
            DafControl::get_instance()->connect(
                "rShot",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect bomb(bomb) control callback
            DafControl::get_instance()->connect(
                "bomb",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect attack(suicideAttack) control callback
            DafControl::get_instance()->connect(
                "attack",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect attackTar(attackTarget) control callback
            DafControl::get_instance()->connect(
                "attackTar",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect stopAuto(stopAutoMode) control callback
            DafControl::get_instance()->connect(
                "stopAuto",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect startAuto(startAutoMode) control callback
            DafControl::get_instance()->connect(
                "startAuto",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect restartFly(restartFlyCtrl) control callback
            DafControl::get_instance()->connect(
                "restartFly",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect stopFly(stopFlyCtrl) control callback
            DafControl::get_instance()->connect(
                "stopFly",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect cfAttack(confirmAttack) control callback
            DafControl::get_instance()->connect(
                "cfAttack",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect 3dMapping(3dMapping) control callback
            DafControl::get_instance()->connect(
                "3dMapping",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect engineEmergencyStop(engineEmergencyStop) control callback
            DafControl::get_instance()->connect(
                "engineEmergencyStop",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect startStabilizedMode(startStabilizedMode) control callback
            DafControl::get_instance()->connect(
                "startStabilizedMode",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect startPositionMode(startPositionMode) control callback
            DafControl::get_instance()->connect(
                "startPositionMode",
                std::bind(&DafUserControl::control_notify, DafUserControl::get_instance(), std::placeholders::_1, std::placeholders::_2));

            // connect param notify functions

            // call user entry
            __user_entry(argc, argv);

            return true;
        }

        // user entry
        void DafUserEntry::__user_entry(int argc, char *argv[])
        {
            new std::thread ([&]
            {
                mp_log_info(DEFAULT_LOGGER, "user entry...");
                if (!WfAgent::WfManager::getInstance()->init())
                {
                    mp_log_error(DEFAULT_LOGGER, "weifei manager init failed");
                    exit(0);
                }
            });

            __registerTopDate();

            //must return, don't block!!!
        }

        void DafUserEntry::__registerTopDate()
        {
            // 监听上级授时数据
            Gazella::GzTopicSubscribe::create_subscribe("topDate", [](const std::string &topic, uint8_t qos, const std::string &message)
                                                        {
                                                            // message 上级授时时间 类型string,格式: 2020-02-31 18:77:00
                                                            // TODO 收到上级时间,对应设备进行时间同步
                                                        },
                                                        1, 2);
        }

    }
}